<?php

/**
 * Dispatcher class
 *
 * Scan for available chart classes
 * Find specified by kind chart,
 * Clear chart directory from old plotted charts
 *
 * @name Dispatcher
 * @author DiMoN
 * @copyright Dmitry Pavlov
 */

class Dispatcher
{
    /**
     * List of available charts
     *
     * @var array
     */
    private $listCharts;

    /**
     * Dispatcher constructor
     *
     */
    public function __construct()
    {
        include(Settings::$ChartsDirectory . Settings::$InterfaceChartsName);
        $this->clearChartsDirectoty();
        $this->scanCharts();
    }

    /**
     * Get specified by kind chart
     *
     * @param string $kind
     * @return object
     */
    public function getChart($kind)
    {
        if (isset($this->listCharts[$kind]))
        {
            return new $this->listCharts[$kind]->ID;
        }
        throw new Exception("Chart '" . $kind . "' not found");
    }

    /**
     * Scan directory where different chart classes are located
     *
     */
    private function scanCharts()
    {
        $chartTypesDirectory = Settings::$ChartTypesDirectory;
        $list = scandir($chartTypesDirectory);

        foreach ($list as $item)
        {
            if ($item != "." && $item != "..")
            {
                if (is_file($chartTypesDirectory . $item) && substr($item, -4) == Settings::FILES_POSTFIX)
                {
                    include($chartTypesDirectory . $item);

                    $itemName = substr($item, 0, -4);

                    if (class_exists($itemName))
                    {
                        $class = new ReflectionClass($itemName);

                        if ($class->implementsInterface("IChart"))
                        {
                            $chart = new ChartStructure();
                            $chart->ID = $class->getMethod("getChartID")->invoke(null);
                            $chart->Name = $class->getMethod("getChartName")->invoke(null);
                            $chart->Type = $class->getMethod("getChartType")->invoke(null);
                            $this->listCharts[$chart->ID] = $chart;
                        }
                    }
                }
            }
        }
    }

    /**
     * Gets XML document with the list of available charts
     *
     * @return string - XMLListCharts document
     */
    public function getXMLListCharts()
    {
        $XMLListCharts = new DOMDocument('1.0', 'UTF-8');
        $root = $XMLListCharts->createElement("charts");
        $XMLListCharts->appendChild($root);

        $sortedListCharts = array();
        foreach($this->listCharts as $key => $chart)
        {
            $sortedListCharts[$chart->Name] = $chart;
        }
        ksort($sortedListCharts);

        foreach($sortedListCharts as $chart)
        {
            $chartElement = $XMLListCharts->createElement("chart");
            $chartElement->setAttribute("ID", $chart->ID);
            $chartElement->setAttribute("name", $chart->Name);
            $chartElement->setAttribute("type", $chart->Type);
            $root->appendChild($chartElement);
        }

        $XMLListCharts->save(Settings::$ResultsChartDirectory . Settings::$XMLListChartsName);
        return $XMLListCharts->saveXML($root);
    }

    /**
     * Clear directory where plotted diagrams are located
     * more than certain period of time
     *
     */
    private function clearChartsDirectoty()
    {
        $diagramsDirectory = Settings::$DiagramsDirectory;
        $list = scandir($diagramsDirectory);
        clearstatcache();

        for ($i = 2; $i < count($list); $i++)
        {
            $item = $diagramsDirectory . $list[$i];
            $time_difference = time() - filemtime($item);

            if ($time_difference > Settings::DELETE_PERIOD * 3600)
            {
                unlink($item);
            }
        }
    }
}

?>